home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 1 / BBS in a box - Trilogy I.iso / Files / Publish / J-L / lpr / lpr source / tcpio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-18  |  12.6 KB  |  600 lines  |  [TEXT/MPS ]

  1. #if !defined(USEDUMP)
  2.     #include "lprlib.h"
  3.     #include "lprdef.h"
  4.     #include "lprfuncs.h"
  5. #else
  6.     #pragma load "lprDumpFile"
  7. #endif
  8.  
  9. #include "GetMyIPAddr.h"
  10. #include "AddressXlation.h"
  11.  
  12. extern main();                        /* for debugging */
  13. extern unsigned char tcpinitok;        /* network code is active */
  14. extern unsigned char pend_conn;        /* connection pending status */
  15. extern unsigned long * Ticks;        /* tick count since Mac startup */
  16. extern unsigned long passtime;        /* time password last stored */
  17. extern unsigned char * filelist;     /* pointer to list of files to process */
  18. extern short currfnum;                /* 0 or reference for open file */
  19. extern unsigned char prtstate;        /* lpr protocol state */
  20. extern unsigned long prtstime;        /* time prtstate last changed */
  21. extern unsigned char netstat[], connstat[], prtstat[];
  22. extern settings_list cs;            /* current settings */
  23. extern short ioerror;                /* result from tcp_init */
  24. extern domainresult dns;            /* domain result structure */
  25. extern unsigned char queueflags[64];    /* flags for our queue */
  26. extern unsigned short queueevents[64];    /* corresponding events */
  27. unsigned char myipnum[4];
  28. static char tcpopnflg = 0;
  29. unsigned char * rcvbuff;            /* stream buffer */
  30. unsigned long rcvlen;                /* stream buffer length */
  31. unsigned char tcpmsg[256];
  32. short tcprefnum;                    /* ioRefNum from MacTCP open */
  33. union {                                /* IP address of remote host */
  34.     unsigned long bin;
  35.     unsigned char chr[4];
  36.     } destaddr;
  37. StreamPtr mystream;                    /* pointer to our stream */
  38.  
  39. void tcp_init(void)
  40. {
  41. pascal Boolean (*filterProc) ();
  42. static unsigned char nullstr[1] = {0};
  43. static unsigned char tcpname[] = "\p.IPP";
  44. IOParam openblk;
  45. struct IPParamBlock ipblk;
  46. TCPiopb cpb;
  47.  
  48. sprintf(tcpmsg, "main at %lx", &main);    /* in case we're using a map */
  49. putln(tcpmsg);                            /* for debugging */
  50.  
  51. /* allocate buffers */
  52. rcvlen = 8192;
  53. rcvbuff = (unsigned char *)NewPtr(rcvlen);
  54. if (rcvbuff == 0L) {
  55.     stgalert("tcp rcv buffer", "NewPtr", rcvlen);
  56.     macend();
  57.     ExitToShell();
  58.     }
  59.                             /* here we open MacTCP */
  60. openblk.ioCompletion = 0;
  61. openblk.ioResult = 0;
  62. openblk.ioNamePtr = tcpname;
  63. openblk.ioRefNum = 0;
  64. openblk.ioPermssn = 0;
  65.  
  66. ioerror = PBOpen((ParmBlkPtr)&openblk, 0);
  67.  
  68. if (ioerror != 0) {
  69.     resetcurs();
  70.     filterProc = DlgFilter;
  71.     sprintf(tcpmsg, "Error %d attempting to open MacTCP.", ioerror);
  72.     c2pstr(tcpmsg);
  73.     ParamText(tcpmsg, nullstr, nullstr, nullstr);
  74.     p2cstr(tcpmsg);
  75.     StopAlert(258, (ModalFilterProcPtr)filterProc);
  76.     ParamText(nullstr, nullstr, nullstr, nullstr);
  77.     return;
  78.     }
  79.  
  80. tcprefnum = openblk.ioRefNum;
  81.  
  82. /* now open a stream to use */
  83. cpb.ioCRefNum = tcprefnum;
  84. cpb.csCode = TCPCreate;
  85. cpb.tcpStream = (StreamPtr)0;
  86. cpb.csParam.create.rcvBuff = rcvbuff;
  87. cpb.csParam.create.rcvBuffLen = rcvlen;
  88. cpb.csParam.create.notifyProc = (TCPNotifyProc)mynotify;
  89. cpb.csParam.create.userDataPtr = 0;
  90. ioerror = PBControl((ParmBlkPtr)&cpb, 0);
  91. if (ioerror != noErr) {
  92.     resetcurs();
  93.     filterProc = DlgFilter;
  94.     sprintf(tcpmsg, "Error %d attempting to open new stream.", ioerror);
  95.     c2pstr(tcpmsg);
  96.     ParamText(tcpmsg, nullstr, nullstr, nullstr);
  97.     p2cstr(tcpmsg);
  98.     StopAlert(258, (ModalFilterProcPtr)filterProc);
  99.     ParamText(nullstr, nullstr, nullstr, nullstr);
  100.     return;
  101.     }
  102. mystream = cpb.tcpStream;
  103.  
  104. /* now open the name resolver */
  105.  
  106. ioerror = OpenResolver((char *)0);    /* use defaults hosts file location */
  107.  
  108. if (ioerror != 0) {
  109.     resetcurs();
  110.     filterProc = DlgFilter;
  111.     sprintf(tcpmsg, "Error %d attempting to open MacTCP name resolver.", ioerror);
  112.     c2pstr(tcpmsg);
  113.     ParamText(tcpmsg, nullstr, nullstr, nullstr);
  114.     p2cstr(tcpmsg);
  115.     StopAlert(258, (ModalFilterProcPtr)filterProc);
  116.     ParamText(nullstr, nullstr, nullstr, nullstr);
  117.     return;
  118.     }
  119.  
  120. ipblk.ioCompletion = 0;
  121. ipblk.ioResult = 0;
  122. ipblk.ioVRefNum = 0;
  123. ipblk.ioCRefNum = tcprefnum;
  124. ipblk.csCode = 15;
  125. ioerror = PBControl((ParmBlkPtr)&ipblk, 0);
  126. memcpy(myipnum, &(ipblk.ourAddress), 4);
  127. sprintf(netstat, "Registered as %d.%d.%d.%d",
  128.     myipnum[0], myipnum[1], myipnum[2], myipnum[3]);
  129. statdlg(0, 0x01);
  130.  
  131. tcpinitok = 1;                    /* remember to shutdown net stuff */
  132. }
  133.  
  134. void tcplgin(void)
  135. {
  136. static struct hostInfo hinfo;
  137. short i;
  138. OSErr rc;
  139. ResultProcPtr rp;
  140.  
  141. /* clear any previous queued events */
  142. for (i = 0; i < 64; i++) {    
  143.     queueflags[i] = 0;
  144.     }
  145.  
  146. hinfo.rtnCode = 0;
  147. strcpy(hinfo.cname, rdhostname());
  148. for (i=0; i < NUM_ALT_ADDRS; i++) {
  149.     (hinfo.addr)[i] = 0;
  150.     }
  151. rp = resolveproc;
  152. rc = StrToAddr(rdhostname(), &hinfo, rp, (char *)&dns);
  153. if (rc == cacheFault) {
  154.     newconn(1);
  155.     sprintf(connstat, "Getting address for %s", rdhostname());
  156.     statdlg(0, 0x02);
  157.     }
  158. else if (rc == noErr) {
  159.     destaddr.bin = (hinfo.addr)[0];
  160.     rc = netopen();
  161.     if (rc != noErr) {
  162.         prtclean();
  163.         stoperr(lopnalrt);
  164.         }
  165.     }
  166. else {                    /* unexpected error */
  167.     sprintf(tcpmsg, "Return code %d from StrToAddr for %s",
  168.         rc, rdhostname());
  169.     prtclean();
  170.     stoperr(numalrt);
  171.     }
  172. }
  173.  
  174. pascal void resolveproc(hptr, userdata)
  175. struct hostInfo *hptr;
  176. char *userdata;
  177. {
  178. domainresult *dptr;
  179.  
  180. dptr = (domainresult *)userdata;
  181. dptr->newresult = 1;
  182. dptr->rc = hptr->rtnCode;
  183. dptr->address = (hptr->addr)[0];
  184. }
  185.  
  186. void tcpevent(void)
  187. {
  188. OSErr rc;
  189. unsigned short newevent;
  190.  
  191. if (dns.newresult > 0) {
  192.     dns.newresult = 0;
  193.     if (pend_conn == 1) {
  194.         if (dns.rc != noErr) {
  195.             sprintf(tcpmsg, "Return code %d from StrToAddr for %s",
  196.                 dns.rc, rdhostname());
  197.             newconn(0);
  198.             prtclean();
  199.             stoperr(numalrt);
  200.             }
  201.         else {
  202.             destaddr.bin = dns.address;
  203.             sprintf(tcpmsg, "Number for %s is %d.%d.%d.%d",
  204.                 rdhostname(), (destaddr.chr)[0], (destaddr.chr)[1],
  205.                 (destaddr.chr)[2], (destaddr.chr)[3]);
  206.             putln(tcpmsg);
  207.             rc = netopen();
  208.             if (rc != noErr) {
  209.                 newconn(0);
  210.                 prtclean();
  211.                 stoperr(lopnalrt);
  212.                 }
  213.             }
  214.         }
  215.     }
  216.  
  217. newevent = getevent();
  218. while (newevent != 0) {
  219.     sprintf(tcpmsg, "New event = %d", newevent);
  220.     putln(tcpmsg);
  221.     switch (newevent) {
  222.         case TCPTerminate:
  223.         case TCPClosing:
  224.                                 tcplgout();
  225.                                 break;
  226.         case TCPULPTimeout:
  227.                                 tcplgout();
  228.                                 break;
  229.         case TCPDataArrival:
  230.         case TCPUrgent:
  231.                                 tcpread();
  232.                                 break;
  233.         case TCPICMPReceived:
  234.         default:
  235.                                 break;
  236.         }
  237.     newevent = getevent();
  238.     }
  239. }
  240.  
  241. OSErr netopen(void)
  242. {
  243. OSErr rc;
  244. TCPiopb openpb;
  245. short pnum;
  246.                         /* use an available port in the lpr range */
  247. for (pnum=721; pnum <= 731; pnum++) {
  248.     openpb.ioCRefNum = tcprefnum;
  249.     openpb.csCode = TCPActiveOpen;
  250.     openpb.tcpStream = mystream;
  251.     openpb.csParam.open.ulpTimeoutValue = 0;
  252.     openpb.csParam.open.ulpTimeoutAction = 0;
  253.     openpb.csParam.open.validityFlags = 0;
  254.     openpb.csParam.open.commandTimeoutValue = 0;
  255.     openpb.csParam.open.remoteHost = destaddr.bin;
  256.     openpb.csParam.open.remotePort = rdportnum();
  257.     memcpy(&(openpb.csParam.open.localHost), myipnum, 4);
  258.     openpb.csParam.open.localPort = pnum;
  259.     openpb.csParam.open.tosFlags = 0;
  260.     openpb.csParam.open.precedence = 0;
  261.     openpb.csParam.open.dontFrag = false;
  262.     openpb.csParam.open.timeToLive = 0;
  263.     openpb.csParam.open.security = false;
  264.     openpb.csParam.open.optionCnt = 0;
  265.     openpb.csParam.open.userDataPtr = 0;
  266.     rc = PBControl((ParmBlkPtr)&openpb, false);
  267.     if (rc != duplicateSocket) break;
  268.     }
  269. if (rc != noErr) return(rc);
  270. newconn(3);
  271. sprintf(connstat, "Connected to %s [%d.%d.%d.%d]",
  272.     rdhostname(), (destaddr.chr)[0], (destaddr.chr)[1],
  273.     (destaddr.chr)[2], (destaddr.chr)[3]);
  274. statdlg(0, 0x02);
  275. prtevent(0L, 0);    /* start sending data */
  276. return(rc);
  277. }
  278.  
  279. pascal void mynotify( streamPtr, code, uptr, terminReason, icmpMsg)
  280. StreamPtr streamPtr;
  281. unsigned short code;
  282. unsigned short terminReason;
  283. struct ICMPReport *icmpMsg;
  284. Ptr uptr;   /* user data pointer */
  285. {
  286. #pragma unused(streamPtr, uptr, terminReason, icmpMsg)
  287. short i;
  288. char found;
  289.  
  290. found = 0;
  291. for (i=0; i < 64; i++) {
  292.     if (queueflags[i] == 0) {
  293.         found = 1;
  294.         break;
  295.         }
  296.     }
  297. if (!found) return;
  298. queueevents[i] = code;
  299. queueflags[i] = 1;
  300. }
  301.  
  302. unsigned short getevent(void)
  303. {
  304. short i;
  305. char found;
  306. unsigned short newevent;
  307.  
  308. found = 0;
  309. for (i=0; i < 64; i++) {
  310.     if (queueflags[i] != 0) {
  311.         found = 1;
  312.         break;
  313.         }
  314.     }
  315. if (!found) return(0);
  316. newevent = queueevents[i];
  317. queueflags[i] = 0;
  318. return(newevent);
  319. }
  320.  
  321. void tcpread(void)
  322. {
  323. static unsigned char readbuff[256];
  324. TCPiopb readpb;
  325. OSErr rc;
  326.  
  327. readpb.ioCRefNum = tcprefnum;
  328. readpb.csCode = TCPRcv;
  329. readpb.tcpStream = mystream;
  330. readpb.csParam.receive.commandTimeoutValue = 0;
  331. readpb.csParam.receive.rcvBuff = readbuff;
  332. readpb.csParam.receive.rcvBuffLen = 256;
  333. readpb.csParam.receive.secondTimeStamp = 0;
  334. readpb.csParam.receive.userDataPtr = 0;
  335. rc = PBControl((ParmBlkPtr)&readpb, 0);
  336. if (rc != noErr) {
  337.     return;
  338.     }
  339. if (readpb.csParam.receive.rcvBuffLen > 0) {
  340.     prtevent(readbuff, readpb.csParam.receive.rcvBuffLen);
  341.     }
  342. }
  343.  
  344. void tcpwrite(s, len)
  345. unsigned char *s;
  346. short len;
  347. {
  348. TCPiopb writepb;
  349. OSErr rc;
  350. struct {
  351.     unsigned short count;
  352.     unsigned char * addr;
  353.     unsigned short end;
  354.     } mywds;
  355.  
  356. mywds.count = len;
  357. mywds.addr = s;
  358. mywds.end = 0;
  359.  
  360. writepb.ioCRefNum = tcprefnum;
  361. writepb.csCode = TCPSend;
  362. writepb.tcpStream = mystream;
  363. writepb.csParam.send.ulpTimeoutValue = 0;
  364. writepb.csParam.send.ulpTimeoutAction = 0;
  365. writepb.csParam.send.validityFlags = 0;
  366. writepb.csParam.send.pushFlag = true;
  367. writepb.csParam.send.urgentFlag = false;
  368. writepb.csParam.send.wdsPtr = (Ptr)&mywds;
  369. writepb.csParam.send.sendFree = 0;
  370. writepb.csParam.send.sendLength = 0;
  371. writepb.csParam.send.userDataPtr = 0;
  372. rc = PBControl((ParmBlkPtr)&writepb, 0);
  373. if (rc != noErr) {
  374.     tcplgout();
  375.     stoperr(wrtalrt);    
  376.     }
  377. }
  378.  
  379. void tcplgout(void)
  380. {
  381. TCPiopb closepb;
  382. OSErr rc;
  383.  
  384. prtclean();
  385. if (pend_conn > 1) {
  386.     closepb.ioCRefNum = tcprefnum;
  387.     closepb.csCode = TCPClose;
  388.     closepb.tcpStream = mystream;
  389.     closepb.csParam.close.ulpTimeoutValue = 0;
  390.     closepb.csParam.close.ulpTimeoutAction = 0;
  391.     closepb.csParam.close.validityFlags = 0;
  392.     closepb.csParam.close.userDataPtr = 0;
  393.     rc = PBControl((ParmBlkPtr)&closepb, 0);
  394.     newconn(0);
  395.     }
  396. }
  397.  
  398. void tcp_end(void)
  399. {
  400. OSErr rc;
  401. TCPiopb relpb;
  402.  
  403. prtclean();
  404.  
  405. if (tcpinitok) {
  406.     rc = CloseResolver();
  407.     tcpinitok = 0;
  408.     }
  409.  
  410. if (mystream != 0) {
  411.     relpb.ioCRefNum = tcprefnum;
  412.     relpb.csCode = TCPRelease;
  413.     relpb.tcpStream = mystream;
  414.     relpb.csParam.create.rcvBuff = rcvbuff;
  415.     relpb.csParam.create.rcvBuffLen = rcvlen;
  416.     rc = PBControl((ParmBlkPtr)&relpb, 0);
  417.     mystream = 0;
  418.     }
  419.  
  420. if (rcvbuff != 0) {
  421.     DisposPtr(rcvbuff);
  422.     }
  423. }
  424.  
  425. void prtclean(void)
  426. {
  427. resetcurs();
  428. prtstate = 0;
  429. prtstime = 0;
  430. if (currfnum != 0) {
  431.     FSClose(currfnum);
  432.     currfnum = 0;
  433.     }
  434. if (filelist != 0) {
  435.     DisposPtr(filelist);
  436.     filelist = 0;
  437.     }
  438. connstat[0] = prtstat[0] = 0;
  439. statdlg(0, 0x06);
  440. }
  441.  
  442. void newconn(n)        /* new pend_conn value is n */
  443. short n;
  444. {
  445. if (n == pend_conn) return;
  446. sprintf(tcpmsg, "pend_conn change from %d to %d",
  447.     pend_conn, n);
  448. putln(tcpmsg);
  449. pend_conn = n;
  450. if (pend_conn == 0) passtime = (*Ticks);
  451. }
  452.  
  453. unsigned char * rdhostname(void)    /* return name part of cs.hostname string */
  454. {
  455. static unsigned char hname[128];
  456. register short i;
  457.  
  458. memcpy(hname, cs.hostname, 128);
  459. for (i=0; i < 128; i++) {
  460.     if (hname[i] == '\0') break;
  461.     if (hname[i] == ':') {
  462.         hname[i] = '\0';
  463.         break;
  464.         }
  465.     }
  466. return(hname);
  467. }
  468.  
  469. short rdportnum(void)        /* return port number from cs.hostname, or default */
  470. {
  471. register short i, len, count, port;
  472. register unsigned char * s;
  473.  
  474. len = strlen(cs.hostname);
  475. if (len < 2) return(HLPD);         /* need at least colon and digit */
  476.  
  477. count = 0;
  478. for (i=0; i < len; i++) {
  479.     if (cs.hostname[i] == ':') {
  480.         count++;
  481.         break;
  482.         }
  483.     }
  484. if (count == 0) return(HLPD);
  485. s = cs.hostname + i + 1;            /* s = host number string */
  486. if (s[0] == '\0') return(HLPD);
  487. port = atoi(s);
  488. if (port != 0) {
  489.     sprintf(tcpmsg, "port number = %d", port);
  490.     putln(tcpmsg);
  491.     return(port);
  492.     }
  493. else return(HLPD);
  494. }
  495.  
  496. void putln (s)                /*  put message in error log */
  497. unsigned char * s;
  498. {
  499. FILE *fp;
  500.  
  501. fp = dbgopen();
  502. if (fp == 0) return;
  503.  
  504. fputs(s, fp);
  505. putc('\015', fp);
  506. if (cs.dblevel == 99) {
  507.     putc('\012', fp);
  508.     fflush(fp);
  509.     dbgwait();
  510.     }
  511.  
  512. dbgclose(fp);
  513. }
  514.  
  515. void tcpdump(msg, data, len)
  516. unsigned char *msg, *data;
  517. short len;
  518. {
  519. short count, i;
  520. FILE *fp;
  521.  
  522. fp = dbgopen();
  523. if (fp == 0) return;
  524.  
  525. fprintf(fp, "%s: %d bytes:", msg, len); 
  526. putc('\015', fp);
  527. if (cs.dblevel == 99) {
  528.     putc('\012', fp);
  529.     fflush(fp);
  530.     dbgwait();
  531.     }
  532.  
  533. count = 0;
  534. for (i=0; i < len; i++) {
  535.     fprintf(fp, "%02x", data[i]);
  536.     count++;
  537.     if (count == 32) {
  538.         putc('\015', fp);
  539.         if (cs.dblevel == 99) {
  540.             putc('\012', fp);
  541.             fflush(fp);
  542.             dbgwait();
  543.             }
  544.         count = 0;
  545.         }
  546.     }
  547. if (count != 0) {
  548.     putc('\015', fp);
  549.     if (cs.dblevel == 99) putc('\012', fp);
  550.     }
  551. putc('\015', fp);
  552. if (cs.dblevel == 99) putc('\012', fp);
  553.  
  554. dbgclose(fp);
  555. }
  556.  
  557. FILE *dbgopen(void)
  558. {
  559. static FILE *fp;
  560. static char debugfile[] = "Ram:tcpdebug";
  561. static char debugser[] = ".aout";
  562.  
  563. if (!cs.dblevel) return(0);
  564.  
  565. if (cs.dblevel == 99) {
  566.     if (tcpopnflg) return(fp);
  567.     else {
  568.         fp = fopen(debugser, "w");
  569.         tcpopnflg = 1;
  570.         return(fp);
  571.         }
  572.     }
  573.  
  574. if (tcpopnflg)
  575.     fp = fopen(debugfile, "a");
  576. else
  577.     fp = fopen(debugfile, "w");
  578. if (fp != 0) tcpopnflg = 1;
  579. return(fp);
  580. }
  581.  
  582. void dbgclose(fp)
  583. FILE *fp;
  584. {
  585. if (cs.dblevel == 99) return;
  586. fclose(fp);
  587. FlushVol("\pRam", 0);
  588. }
  589.  
  590. void dbgwait(void)
  591. {
  592. static unsigned long *Ticks = 0x16a;
  593. unsigned long limit;
  594.  
  595. limit = (*Ticks) + 15;
  596. while (limit > (*Ticks));
  597. }
  598.  
  599.  
  600.